package com.gr100.biz.api.order;

import com.alibaba.fastjson.JSONObject;
import com.gr100.biz.api.order.hex.ValidateHex;
import com.jfinal.aop.Before;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.DbPro;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.gr100.biz.kit.bmap.GeoCoder;
import com.gr100.biz.kit.bmap.GeoUtils;
import com.mysql.jdbc.StringUtils;

/**
 * Created by YFsoft on 16/3/14.
 */
public class OrderService {

    private static final Log logger = Log.getLog("OrderService");

    DbPro api = Db.use("api");
    DbPro ec = Db.use("ec");
    DbPro erp = Db.use("erp");

    /**
     * 创建订单
     * @param
     * @author james 2016-03-02
     */
    @Before(Tx.class)
    public synchronized Map createOrder(String type,String toProvince,String toCity,String toName,String toPhone,String toStreet,String total,String finalAmount,String discount,int gCoinChecked,String gCoin,String remark,String areaName,String shopName,String uid,String couponId,String par,String bookdate,String expresscost,String expressname,String expresstype,String deliveryTime,int UserTimingCouponId,int MemberTimingCouponId,String TimingPrice,String mj_title,String mj_amount,String couponDiscountId,String couponDiscountPar){

        Map<String,Object> map = new HashMap<String,Object>();

        try {

            //区域及果饮店特殊处理
            int areaId = 0;
            int shopId = 0;
            double lng = 119.440118;
            double lat = 32.400416;
            String confidence = "100";
            String level = "";

            JSONObject json;
            //先到erp.gr_lbs_coordinate 表里查看是否已被客服标记过
            //如果存在，代表已标记过，那就把erp.gr_lbs_coordinate 表里的经纬度及地址属性反更新到订单表里
            //如果不存在，代码还未标记过，那就调用户百度提供的逆推接口，来获取经纬度及地址属性

            String sql = "select * from gr_lbs_coordinate a where a.toProvince = ? and a.toCity = ? and a.toStreet = ? ";
            List<Record> coor = erp.find(sql, toProvince, toCity, toStreet);

            if(coor.size() == 1){
                lng = Double.valueOf(coor.get(0).getStr("lng"));
                lat = Double.valueOf(coor.get(0).getStr("lat"));
                level = coor.get(0).getStr("level");
            }else{
                json=GeoCoder.Geocoding(toStreet,toCity);

                //获取经纬度及可信度
                JSONObject result = json.getJSONObject("result");
                if(result != null){
                    JSONObject location = result.getJSONObject("location");
                    confidence = result.getString("confidence");
                    level = result.getString("level");
                    if(location != null){
                        lng = Double.valueOf(location.getString("lng"));
                        lat = Double.valueOf(location.getString("lat"));
                    }else{
                        lng = 119.440118;
                        lat = 32.400416;
                    }
                }else{
                    confidence = "0";
                    lng = 119.440118;
                    lat = 32.400416;
                }
            }

            if(lng == 0){
                lng = 119.440118;
            }

            if(lat == 0){
                lat = 32.400416;
            }

            GeoUtils geoutils = new GeoUtils();

            Map mapresult = new HashMap();
            mapresult = geoutils.isPointInArea("a5107dfd89e6d3baf2610e009bd0d891", 2, lng, lat); //返回分区ID  如果没有匹配返回0

            if(Integer.parseInt(mapresult.get("code").toString())==0){

            }else{
                areaId = Integer.parseInt(mapresult.get("areainfootherid").toString());
                int t = Integer.parseInt(mapresult.get("id").toString());

                if(areaId > 0){
                    List<Record> areas = erp.find("select a.warehouse from gr_lbs_project_area a where a.id = ?",t);
                    if(areas.size() == 1){
                        shopId = areas.get(0).getInt("warehouse");
                    }
                }
            }

            String sjc = Long.toString(System.currentTimeMillis());

            String prefix = "";
            if(type.length() == 1){
                prefix = "0";
            }
            String orderid = prefix+type+sjc;
            String groupNo = "G"+prefix+type+sjc;

            Order order = new Order(orderid,groupNo,type,toProvince,toCity,toName,toPhone,toStreet,total,finalAmount,discount,remark,areaId,areaName,shopId,shopName,uid,couponId,par,sjc,gCoinChecked,gCoin,lng,lat,level,confidence,bookdate,expresscost,expressname,expresstype,deliveryTime,UserTimingCouponId,MemberTimingCouponId,TimingPrice,mj_title,mj_amount,couponDiscountId,couponDiscountPar);

            //非空验证
            order.validate();

            //验证购物车内是否有商品
            if(!order.checkExists()){
                throw new ValidateHex(-708,"There is no data in the shopping cart","购物车内没有数据");
            }

            //验证购物车内商品是否下架
            if(!order.checkInvalid()){
                throw new ValidateHex(-709,"The goods have been off the shelf","购物车内有已下架的商品");
            }

            //验证商品库存是否充足
            if(!order.checkInventory()){
                throw new ValidateHex(-714,"Inventory shortage","购买的商品库存不足");
            }

            //验证订单原价是否正确
            if(!order.checkAmount()){
                throw new ValidateHex(-719,"Order price calculation error","订单原价计算有误");
            }

            //验证会员折扣是否正确
            if(!order.checkDiscount()){
                throw new ValidateHex(-717,"Member discount calculation error","会员折扣计算有误");
            }

            //验证优惠券是否正确
            if(!order.checkCoupon()){
                throw new ValidateHex(-718,"Coupon amount calculation error","优惠券金额计算有误");
            }

            //验证折扣优惠券是否正确
            if(!order.checkCouponDiscount()){
                throw new ValidateHex(-727,"DiscountCoupon amount calculation error","折扣优惠券金额计算有误");
            }

            //验证活动余额是否正确
            if(!order.checkgCoin()){
                throw new ValidateHex(-720,"Activity balance calculation error","活动余额计算有误");
            }

            //验证订单实付金额是否正确
            if(!order.checkFinalAmount()){
                throw new ValidateHex(-716,"Actual payment calculation error","实付金额计算有误");
            }

            //验证会员定时券
            if(MemberTimingCouponId > 0 && !order.checkMemberTimingCouponId()){
                throw new ValidateHex(-725,"Membership timing error","会员定时券有误");
            }

            //验证用户定时券
            if(UserTimingCouponId > 0 && !order.checkUserTimingCouponId()) {
                throw new ValidateHex(-726,"User timing error","用户定时券有误");
            }

            //生成订单
            order.save();

            //更新活动余额及余额流水
            if(gCoinChecked == 1 && Double.valueOf(gCoin) > 0){
                String content = "订单"+groupNo+"使用活动余额支付,扣除账户活动余额"+finalAmount+"元.";
                order.lessengCoin(uid, Double.valueOf(gCoin), content);
            }

            //更新优惠券使用状态
            if(couponId.length() > 0 && !"0".equals(couponId)){
                order.updateCouponId();
            }

            //更新折扣优惠券使用状态
            if(couponDiscountId.length() > 0 && !"0".equals(couponDiscountId)){
                order.updateDiscountCouponId();
            }

            //更新用户定时券使用状态
            if(UserTimingCouponId > 0){
                order.updateUserCouponId();
            }

            //更新会员定时券使用状态
            if(MemberTimingCouponId > 0){
                order.updateMemberCouponId();
            }

            //扣减商品库存
            order.minusInventory();

            //删除购物车
            order.delCart();

            Map<String,Object> p = new HashMap<String,Object>();
            p.put("groupNo",groupNo);
            p.put("orderid",orderid);
            p.put("total",finalAmount);

            map.put("data", p);

        }catch (ValidateHex validateHex) {
            map.put("errno", validateHex.errno);
            map.put("code", validateHex.code);
            map.put("msg", validateHex.message);
        }

        return map;
    }

    /**
     * 创建充值订单
     * @param
     * @author james 2016-04-19
     */
    @Before(Tx.class)
    public synchronized Map recharge(String uid,double amount){

        Map<String,Object> map = new HashMap<String,Object>();

        try {

            String sjc = Long.toString(System.currentTimeMillis());

            String orderid = "C"+sjc;

            //非空验证
            if(StringUtils.isNullOrEmpty(uid)){
                throw new ValidateHex(-731,"Recharge users can not be empty","充值用户不能为空");
            }
            if(amount <= 0){
                throw new ValidateHex(-732,"Recharge amount can not be empty","充值金额不能为空");
            }

            //生成充值订单
            Record recharge = new Record();
            recharge.set("pay", amount);
            recharge.set("uid", uid);
            recharge.set("type", 1);
            recharge.set("orderid", orderid);
            //order.set("arrival", amount);
            recharge.set("createAt", sjc);
            recharge.set("updateAt", sjc);
            ec.save("gr_rechargerecord", recharge);


            Map<String,Object> p = new HashMap<String,Object>();
            p.put("errno",0);
            p.put("orderid",orderid);
            p.put("amount",amount);

            map.put("data", p);

        }catch (ValidateHex validateHex) {
            map.put("errno", validateHex.errno);
            map.put("code", validateHex.code);
            map.put("msg", validateHex.message);
        }

        return map;
    }
    /**
     * 用户充值支付回调
     * @param
     * @author james 2016-04-19
     */
    @Before(Tx.class)
    public Map rechargenotify(String orderid,double amount){

        Map<String,Object> map = new HashMap<String,Object>();

        try {

            if(StringUtils.isNullOrEmpty(orderid)){
                throw new ValidateHex(-733,"Order number cannot be empty","订单编号不能为空");
            }

            if(amount < 0){
                throw new ValidateHex(-734,"Amount can not be negative","金额不能为负数");
            }

            List<Record> list = ec.find("select a.* from gr_rechargerecord a where a.orderid = ? and a.type = 1", orderid);

            if(list.size() == 1){

                String uid = list.get(0).getStr("uid");
                double balance = 0;
                double arrival = 0;

                List<Record> users = api.find("select a.* from gr_login_info a where a.id = ?", uid);
                if(users.size() == 1){
                    balance = users.get(0).getDouble("balance");
                }

                String sjc = Long.toString(System.currentTimeMillis()).substring(0, 10);


                if(amount == 100){
                    arrival = 106;
                }else if(amount == 300){
                    arrival = 318;
                }else if(amount == 500){
                    arrival = 538;
                }else if(amount == 1000){
                    arrival = 1068;
                }else{
                    arrival = amount;
                }

                api.update("update gr_login_info set balance = balance + "+arrival+" where id = ?", uid);
                ec.update("update gr_rechargerecord set type = 2,arrival = ?,updateAt = ? where orderid = ?", arrival, sjc, orderid);

                String content = "订单"+orderid+"使用微信充值,账户余额增加"+arrival+"元";
                Record money = new Record();
                money.set("uid", uid);
                money.set("newbalance", arrival);
                money.set("beforebalance", balance);
                money.set("afterbalance", balance+arrival);
                money.set("content", content);
                money.set("createAt", sjc);
                money.set("updateAt", sjc);
                ec.save("gr_user_money", money);
            }
            Map<String,Object> p = new HashMap<String,Object>();
            p.put("errno",0);
            p.put("code","");

            map.put("data", p);
        }catch (ValidateHex validateHex) {
            map.put("errno", validateHex.errno);
            map.put("code", validateHex.code);
            map.put("msg", validateHex.message);
        }

        return map;
    }

    /**
     * 支付
     * @param
     * @author james 2016-04-06
     */
    @Before(Tx.class)
    public Map pay(String orderid,double amount,String payway){

        Map<String,Object> map = new HashMap<String,Object>();

        try {

            if(StringUtils.isNullOrEmpty(orderid)){
                throw new ValidateHex(-721,"Order number cannot be empty","订单编号不能为空");
            }

            if(amount < 0){
                throw new ValidateHex(-722,"Amount can not be negative","金额不能为负数");
            }

            if(StringUtils.isNullOrEmpty(payway)){
                throw new ValidateHex(-723,"The payment method cannot be empty","支付方式不能为空");
            }

            List<Record> list = ec.find("select a.* from gr_final_order_group a,gr_final_order b where a.groupNo = ? and a.groupNo = b.groupNo and b.status in (1000,1500)", orderid);
            if(list.size() == 1){

                String uid = list.get(0).getStr("uid");
                List<Record> user = api.find("select * from gr_login_info a where a.id = ?", uid);
                double beforebalance = user.get(0).getDouble("balance");

                if("余额支付".equals(payway)){
                    if(beforebalance < amount){
                        throw new ValidateHex(-724,"There is no data in the shopping cart","余额不足");
                    }

                    String sjc = Long.toString(System.currentTimeMillis()).substring(0, 10);
                    double afterbalance = beforebalance - amount;

                    String content = "订单G"+sjc+"使用余额支付,扣除账户余额"+amount+"元.";
                    Record money = new Record();
                    money.set("uid", uid);
                    money.set("newbalance", amount);
                    money.set("beforebalance", beforebalance);
                    money.set("afterbalance", afterbalance);
                    money.set("content", content);
                    money.set("createAt", sjc);
                    money.set("updateAt", sjc);
                    ec.save("gr_user_money", money);

                    api.update("update gr_login_info set balance = ? where id = ?", afterbalance, uid);

                    notify(orderid,amount*100,payway);
                }else if("货到付款".equals(payway)){
                    notify(orderid,amount*100,payway);
                }

            }else{
                throw new ValidateHex(-724,"No order to pay","没有订单要支付");
            }
            Map<String,Object> p = new HashMap<String,Object>();
            p.put("errno",0);
            p.put("code","");

            map.put("data", p);
        }catch (ValidateHex validateHex) {
            map.put("errno", validateHex.errno);
            map.put("code", validateHex.code);
            map.put("msg", validateHex.message);
        }

        return map;
    }

    /**
     * 支付回调
     * @param
     * @author james 2016-04-06
     */
    @Before(Tx.class)
    public Map notify(String orderid,double amount,String payway){

        Map<String,Object> map = new HashMap<String,Object>();

        try {

            if(StringUtils.isNullOrEmpty(orderid)){
                throw new ValidateHex(-721,"Order number cannot be empty","订单编号不能为空");
            }

            if(amount < 0){
                throw new ValidateHex(-722,"Amount can not be negative","金额不能为负数");
            }

            if(StringUtils.isNullOrEmpty(payway)){
                throw new ValidateHex(-723,"The payment method cannot be empty","支付方式不能为空");
            }

            List<Record> list = ec.find("select a.uid,b.orderid from gr_final_order_group a,gr_final_order b where a.groupNo = ? and a.groupNo = b.groupNo and b.status in (1000,1500)", orderid);

            if(list.size() == 1){

                String uid = list.get(0).getStr("uid");
                String oid = list.get(0).getStr("orderid");
                String sjc = Long.toString(System.currentTimeMillis()).substring(0, 10);

                Record pay = new Record();
                pay.set("oid", orderid);
                pay.set("way", payway);

                NumberFormat nf = NumberFormat.getInstance();
                nf.setMaximumFractionDigits(2);

                double je = amount/100;

                pay.set("count", je);
                pay.set("createAt", sjc);
                pay.set("updateAt", sjc);
                ec.save("gr_order_pay", pay);

                String sql = "SELECT aa.oid,SUM(yj) yj,SUM(sfje) sfje,SUM(yhq) yhq,SUM(hdye) hdye,SUM(hyzk) hyzk,SUM(yf) yf FROM ( " +
                        "SELECT " +
                        "a.oid," +
                        "CASE WHEN a.way = '原价' THEN a.count ELSE 0 END yj," +
                        "CASE WHEN a.way = '实付金额' THEN a.count ELSE 0 END sfje," +
                        "CASE WHEN a.way = '优惠券' THEN a.count ELSE 0 END yhq," +
                        "CASE WHEN a.way = '活动余额' THEN a.count ELSE 0 END hdye," +
                        "CASE WHEN a.way = '会员折扣' THEN a.count ELSE 0 END hyzk, " +
                        "CASE WHEN a.way = '运费' THEN a.count ELSE 0 END yf " +
                        "FROM gr_order_pay a " +
                        "WHERE a.oid = '"+orderid+"' ) aa " +
                        "GROUP BY aa.oid";
                List<Record> p = ec.find(sql);
                logger.info(""+sql);

                double yj = p.get(0).getDouble("yj");           //原价
                double sfje = p.get(0).getDouble("sfje");       //实付金额
                double yhq = p.get(0).getDouble("yhq");         //优惠券
                double hdye = p.get(0).getDouble("hdye");       //活动余额
                double hyzk = p.get(0).getDouble("hyzk");       //会员折扣
                double yf = p.get(0).getDouble("yf");       //运费


                String payDetails = payway+":"+je+"元;(原价:"+yj+"元;";
                if(hyzk>0){
                    payDetails += "会员折扣:"+hyzk+"元;";
                }
                if(yhq>0){
                    payDetails += "优惠券抵扣:"+yhq+"元;";
                }
                if(hdye>0){
                    payDetails += "活动余额:"+hdye+"元;";
                }
                if(yf>0){
                    payDetails += "运费:"+yf+"元;";
                }

                payDetails += ")";

                ec.update("update gr_final_order_group set payway = ?,payTime=?,payDetails=? where groupNo = ?",payway,sjc,payDetails,orderid);
                ec.update("update gr_final_order set status = 2000 where groupNo = ?",orderid);

                Record log = new Record();
                log.set("dataId", oid);
                log.set("type", "用户操作");
                log.set("uid", uid);
                log.set("remark", "用户支付成功");
                log.set("createdate", sjc);
                log.set("createAt", sjc);
                log.set("updateAt", sjc);
                ec.save("gr_operate_log", log);
            }
            Map<String,Object> p = new HashMap<String,Object>();
            p.put("errno",0);
            p.put("code","");

            map.put("data", p);
        }catch (ValidateHex validateHex) {
            map.put("errno", validateHex.errno);
            map.put("code", validateHex.code);
            map.put("msg", validateHex.message);
        }

        return map;
    }
}




